﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

using GameEngine.Graphics;
using GameEngine.TileMap;
using GameEngine.Help;

namespace GameEngine.Graphics.Light
{
    public class LightManager
    {
        private static Vector2[] LightPosition;
        private static QuadRenderComponent Render;
        private static ShadowmapResolver shadowmapResolver;
        private static LightArea[] LightArea;
        private static RenderTarget2D scrennShadows;
        private static GraphicsDevice graphicsDevice;
        private static Color[] Colors;
        private static Vector2[] LightPositionOriginal;

        private static Texture2D TEST;

        public static QuadRenderComponent QRC
        {
            get { return Render; }
            set { Render = value; }
        }

        public static GraphicsDevice GraphicsDevice
        {
            get { return graphicsDevice; }
            set { graphicsDevice = value; }
        }

        public static void Init(GraphicsDevice GD, Game game)
        {
            graphicsDevice = GD;
            Render = new QuadRenderComponent(game);
        }

        public static void LoadContent(ContentManager Content)
        {
            shadowmapResolver = new ShadowmapResolver(graphicsDevice, Render, ShadowmapSize.Size256, ShadowmapSize.Size1024);
            shadowmapResolver.LoadContent(Content);

            LightPosition = new Vector2[10];
            LightPosition[0] = new Vector2(20, 140);
            LightPosition[1] = new Vector2(800, 500);
            LightPosition[2] = new Vector2(200, 900);
            LightPosition[3] = new Vector2(200, 2000);
            LightPosition[4] = new Vector2(200, 1300);
            LightPosition[5] = new Vector2(1200, 1200);
            LightPosition[6] = new Vector2(600, 1000);
            LightPosition[7] = new Vector2(300, 1700);
            LightPosition[8] = new Vector2(200, 500);
            LightPosition[9] = new Vector2(600, 300);

            LightArea = new LightArea[10];
            LightArea[0] = new LightArea(GraphicsDevice, ShadowmapSize.Size512);
            LightArea[1] = new LightArea(GraphicsDevice, ShadowmapSize.Size512);
            LightArea[2] = new LightArea(GraphicsDevice, ShadowmapSize.Size512);
            LightArea[3] = new LightArea(GraphicsDevice, ShadowmapSize.Size512);
            LightArea[4] = new LightArea(GraphicsDevice, ShadowmapSize.Size512);
            LightArea[5] = new LightArea(GraphicsDevice, ShadowmapSize.Size512);
            LightArea[6] = new LightArea(GraphicsDevice, ShadowmapSize.Size512);
            LightArea[7] = new LightArea(GraphicsDevice, ShadowmapSize.Size512);
            LightArea[8] = new LightArea(GraphicsDevice, ShadowmapSize.Size512);
            LightArea[9] = new LightArea(GraphicsDevice, ShadowmapSize.Size512);

            Colors = new Color[10];
            Colors[0] = Color.White;
            Colors[1] = Color.White;
            Colors[2] = Color.White;
            Colors[3] = Color.Red;
            Colors[4] = Color.White;
            Colors[5] = Color.White;
            Colors[6] = Color.White;
            Colors[7] = Color.White;
            Colors[8] = Color.White;
            Colors[9] = Color.White;

            scrennShadows = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height*2);
            Render.LoadContent();

            TEST = Content.Load<Texture2D>(@"TileMap\TextureMap\EasyWall");

            LightPositionOriginal = LightPosition;
            
        }

        public void Update()
        {


        }

        public void Draw(TileMap.TileMap Map)
        {
           

            for (int i = 0; i < LightPosition.Length; i++)
            {
                LightPosition[i] += GameEngine.Input.MovementNow();
                LightArea[i].LightPosition = LightPosition[i]; 
                LightArea[i].BeginDrawingShadowCasters();
                DrawCasters(LightArea[i], Map);
                LightArea[i].EndDrawingShadowCasters();
                shadowmapResolver.ResolveShadows(LightArea[i].RenderTarget, LightArea[i].RenderTarget, LightPosition[i]);
            }

            graphicsDevice.SetRenderTarget(scrennShadows);
            graphicsDevice.Clear(Color.Black);
            Camera.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);
            for (int i = 0; i < LightPosition.Length; i++)
            {
                Camera.TryDraw(LightArea[i].RenderTarget, LightPosition[i] - LightArea[i].LightAreaSize * 0.5f, Colors[i]);
            }
            Camera.SpriteBatch.End();

            GraphicsDevice.SetRenderTarget(null);
            GraphicsDevice.Clear(Color.Black);

            DrawGround(Map);

            BlendState blendState = new BlendState();
            blendState.ColorSourceBlend = Blend.DestinationColor;
            blendState.ColorDestinationBlend = Blend.SourceColor;

            Camera.SpriteBatch.Begin(SpriteSortMode.Immediate, blendState);
            Camera.TryDraw(scrennShadows, new Vector2(0,0), Color.White);
            Camera.SpriteBatch.End();

            DrawScrene(Map);
        }

        private void DrawCasters(LightArea lightArea, TileMap.TileMap Map)
        {
            
            Camera.SpriteBatch.Begin();
            //Hindernisse für das Licht zeichnen
            for (int y = 0; y < Map.TilesY; y++)
            {
                for (int x = 0; x < Map.TilesX; x++)
                {
                    Vector2 Temp = lightArea.ToRelativePosition(new Vector2(y * 50, x * 50));
                    if (Map.TextureMap[x, y] > 10)
                    {
                        //Camera.TryDraw(Map.TextureMapTexture[Map.TextureMap[x, y]], Temp, null, Color.White, 0f, Temp, 0.5f, SpriteEffects.None, 0f);
                        Camera.TryDrawCasters(Map.LightMapTexture[1], Temp, Color.Black);
                        //Camera.SpriteBatch.Draw(Map.TextureMapTexture[Map.TextureMap[x, y]], Temp, new Rectangle((int)Math.Round(Temp.X), (int)Math.Round(Temp.Y), 50, 50), Color.Black, 0f, Vector2.Zero, 0.5f, SpriteEffects.None, 0f);
                    }
                }
            }
            //HIER WEITERMACHEN !!!
            GameObjektManager.DrawShadows(lightArea);
            //Camera.SpriteBatch.Draw(Player, lightArea.ToRelativePosition(new Vector2(512, 362)), null, Color.White, 0f, Vector2.Zero, 0.5f, SpriteEffects.None, 0f);
            Camera.SpriteBatch.End();
        }

        private void DrawScrene(TileMap.TileMap Map)
        {
            Camera.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
            //Hinderniss für das Licht zeichnen
            for (int y = 0; y < Map.TilesY; y++)
            {
                for (int x = 0; x < Map.TilesX; x++)
                {
                    Vector2 Temp = (new Vector2(y *100, x * 100));
                    if (Map.TextureMap[x, y] > 10)
                    {
                        Camera.TryDraw(Map.TextureMapTexture[Map.TextureMap[x, y]], Temp, null, Color.White, 0f, Temp, 0.5f, SpriteEffects.None, 0f);
                        //Camera.TryDraw(Map.TextureMapTexture[Map.TextureMap[x, y]], Temp, Color.White);
                    }
                }
            }
            //Camera.TryDraw(TEST,new Vector2(60,60), Color.White);
            //Camera.TryDraw(Map.TextureMapTexture[2], (new Vector2(2 * 100, 0)), Color.White);
            Camera.SpriteBatch.End();

        }

        private void DrawGround(TileMap.TileMap Map)
        {
            Camera.SpriteBatch.Begin();
            for (int y = 0; y < Map.TilesY; y++)
            {
                for (int x = 0; x < Map.TilesX; x++)
                {
                    Vector2 Temp = new Vector2(y * 100, x * 100);
                    if (Map.TextureMap[x, y] < 10)
                    {
                       Camera.TryDraw(Map.TextureMapTexture[Map.TextureMap[x, y]], Temp, null, Color.White, 0f, Temp, 0.5f, SpriteEffects.None, 0f);
                        //Camera.TryDraw(Map.TextureMapTexture[Map.TextureMap[x, y]], Temp, Color.White);
                    }
                }
            }
            Camera.SpriteBatch.End();
        }
    }
}
